package com.whfc.emp.service.impl;

import com.whfc.common.enums.DelFlag;
import com.whfc.common.enums.HelmetState;
import com.whfc.common.enums.LocaleState;
import com.whfc.common.exception.BizException;
import com.whfc.common.mqtt.MqttMessageParam;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.third.map.MapApi;
import com.whfc.common.third.map.MapLoc;
import com.whfc.common.util.DateUtil;
import com.whfc.common.util.Gps;
import com.whfc.common.util.PositionUtil;
import com.whfc.emp.clean.DirtyDataCleaner;
import com.whfc.emp.dao.AppEmpDataMapper;
import com.whfc.emp.dao.AppEmpMapper;
import com.whfc.emp.dao.AppEmpWorkTypeMapper;
import com.whfc.emp.dto.AppEmpDTO;
import com.whfc.emp.entity.AppDeviceCardLog;
import com.whfc.emp.entity.AppEmp;
import com.whfc.emp.entity.AppEmpData;
import com.whfc.emp.entity.AppEmpWorkType;
import com.whfc.emp.enums.AttendState;
import com.whfc.emp.enums.NetState;
import com.whfc.emp.manager.AppEmpDataManager;
import com.whfc.emp.mqtt.MqttConfig;
import com.whfc.emp.param.AddEmpDataParam;
import com.whfc.emp.param.EmpInfoParam;
import com.whfc.emp.redis.CardDataRedisDao;
import com.whfc.emp.redis.EmpPolygonWKTRedisDao;
import com.whfc.emp.service.AppInnerService;
import com.whfc.flux.dao.AppDeviceCardLogDao;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.*;

/**
 * @ClasssName AppInnerServiceImpl
 * @Description 内部应用
 * @Author hw
 * @Date 2021/1/5 11:56
 * @Version 1.0
 */
@DubboService(interfaceClass = AppInnerService.class, version = "1.0.0", timeout = 5000)
public class AppInnerServiceImpl implements AppInnerService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private EmpPolygonWKTRedisDao empPolygonWKTRedisDao;

    @Autowired
    private AppEmpDataManager appEmpDataManager;

    @Autowired
    private AppEmpMapper appEmpMapper;

    @Autowired
    private AppEmpWorkTypeMapper appEmpWorkTypeMapper;

    @Autowired
    private AppDeviceCardLogDao appDeviceCardLogDao;

    @Autowired
    private CardDataRedisDao cardDataRedisDao;

    @Autowired
    private AppEmpDataMapper appEmpDataMapper;

    @Autowired
    private DirtyDataCleaner dirtyDataCleaner;

    @Autowired
    private MapApi mapApi;

    @Autowired(required = false)
    private MqttConfig.MqttMessageSender mqttMessageSender;

    @Value("${mqtt.enabled}")
    private Boolean mqttEnable;

    @Override
    public void buildEmpData(Integer empId, Integer deviceId, Date time, Double lat, Double lng) {
        for (int i = 0; i < 50; i++) {
            // 光谷广场114.398408,30.505931
            Gps gps1 = new Gps(lat, lng);
            Gps randomLatLng = PositionUtil.getRandomLatLng(gps1);
            AppDeviceCardLog log = new AppDeviceCardLog();
            log.setEmpId(empId);
            log.setTime(time);
            log.setLat(randomLatLng.getLat());
            log.setLng(randomLatLng.getLng());
            log.setLatWgs84(randomLatLng.getLat());
            log.setLngWgs84(randomLatLng.getLng());
            log.setDeviceId(deviceId);
            MapLoc loc = mapApi.geocode(randomLatLng.getLng(), randomLatLng.getLat());
            log.setLocation(loc.getAddress());
            appEmpDataManager.addHelmetData(log);
            time = DateUtil.addSeconds(time, 30);
        }
    }

    @Override
    public void updateEmpInfo(List<EmpInfoParam> param) throws Exception {
        for (EmpInfoParam empInfoParam : param) {
            String idcardNo = empInfoParam.getIdcardNo();
            String phone = empInfoParam.getPhone();
            String nation = empInfoParam.getNation();
            String org = empInfoParam.getOrg();
            String address = empInfoParam.getAddress();
            appEmpMapper.updateEmpInfoByIdCardNo(idcardNo, phone, nation, org, address);
        }
    }

    @Override
    public void syncWorkTypeId(Integer deptId) {
        List<AppEmpDTO> appEmpDTOS = appEmpMapper.selectByDeptId(deptId, null);
        Set<String> workTypeSet = new HashSet<>();
        for (AppEmpDTO appEmpDTO : appEmpDTOS) {
            String workTypeName = appEmpDTO.getWorkTypeName();
            workTypeSet.add(workTypeName);
        }

        for (String workTypeName : workTypeSet) {
            AppEmpWorkType appEmpWorkType = appEmpWorkTypeMapper.selectByDeptIdAndName(deptId, workTypeName);
            if (appEmpWorkType == null) {
                continue;
            }
            Integer workTypeId = appEmpWorkType.getId();
            appEmpMapper.updateWorkTypeId(workTypeId, workTypeName, deptId);
        }
    }

    @Override
    public void refreshPolygonWKT(Integer deptId) {
        logger.info("刷新人员polygonWKT服务,deptId:{}", deptId);
        empPolygonWKTRedisDao.delPolygonWKT(deptId);
    }

    @Override
    public void amendHelmetData(List<AppDeviceCardLog> list) throws BizException {
        logger.info("修正安全帽数据服务,param:{}", list.toString());
        if (list.size() == 0) {
            return;
        }
        for (AppDeviceCardLog deviceCardLog : list) {
            MapLoc loc = mapApi.geocode(deviceCardLog.getLng(), deviceCardLog.getLat());
            deviceCardLog.setLocation(loc.getAddress());
        }

        // 保存硬件数据
        appDeviceCardLogDao.batchInsert(list);

        // 刷新缓存
        Date logDate = DateUtil.getDate(list.get(0).getTime());
        cardDataRedisDao.delete(list.get(0).getEmpId(), logDate);

    }

    /**
     * lng_flag,
     * lat_flag,
     * lng,
     * lat,
     * gps_time,
     * lng_wgs84,
     * lat_wgs84,
     * battery_state,
     * battery_power
     *
     * @param time
     * @param empId
     * @param deviceId
     * @param lat
     * @param lng
     * @throws BizException
     */
    @Override
    public void addEmpData(Date time, Integer empId, Integer deviceId, Double lat, Double lng) throws BizException {
        logger.info("添加安全帽数据:time:{},empId:{},deviceId:{},lat:{},lng:{}",
                time, empId, deviceId, lat, lng);
        // 插入实时数据
        AppEmpData record = new AppEmpData();
        record.setGpsTime(time);
        record.setEmpId(empId);
        record.setDeviceId(deviceId);
        record.setNetState(NetState.ONLINE.getValue());
        record.setHelmetState(HelmetState.NORMAL.getValue());
        record.setLocaleState(LocaleState.IN.getValue());
        record.setAttendState(AttendState.ATTEND.getValue());
        record.setTime(time);
        record.setLat(lat);
        record.setLatFlag("N");
        record.setLatWgs84(lat);
        record.setLng(lng);
        record.setLngFlag("E");
        record.setLngWgs84(lng);
        record.setBatteryPower(89);
        record.setBatteryState(2);
        appEmpDataMapper.insertOrUpdate(record);

        // cha入轨迹
        List<AppDeviceCardLog> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Gps gps1 = new Gps(lat, lng);
            Gps randomLatLng = PositionUtil.getRandomLatLng(gps1);
            AppDeviceCardLog log = new AppDeviceCardLog();
            log.setEmpId(empId);
            log.setDeviceId(deviceId);
            log.setTime(time);
            log.setLat(randomLatLng.getLat());
            log.setLng(randomLatLng.getLng());
            log.setLatWgs84(randomLatLng.getLat());
            log.setLngWgs84(randomLatLng.getLng());
            log.setBatteryPower(88);
            MapLoc loc = mapApi.geocode(randomLatLng.getLng(), randomLatLng.getLat());
            log.setLocation(loc.getAddress());
            log.setDelFlag(DelFlag.UNDELETE.getValue());
            time = DateUtil.addMinutes(time, -3);
            list.add(log);
        }
        appDeviceCardLogDao.batchInsert(list);
    }

    @Override
    public void batchAddEmpData(AddEmpDataParam param) throws BizException {
        logger.info("批量添加安全帽数据服务,param:{}", param.toString());
        Random random = new Random();
        List<Integer> empIds = param.getEmpIds();
        int cnt = 0;
        for (Integer empId : empIds) {
            try {
                AppEmpData appEmpData = appEmpDataMapper.selectByEmpId(empId);
                if (appEmpData == null) {
                    continue;
                }
                Date time = param.getTime();
                appEmpData.setTime(time);
                appEmpData.setGpsTime(time);
                appEmpData.setUpdateTime(time);
                appEmpData.setNetState(NetState.ONLINE.getValue());
                appEmpData.setHelmetState(HelmetState.NORMAL.getValue());
                appEmpData.setLocaleState(LocaleState.IN.getValue());
                appEmpData.setAttendState(AttendState.ATTEND.getValue());
                appEmpDataMapper.updateByPrimaryKeySelective(appEmpData);

                // 插入轨迹 75分钟
                List<AppDeviceCardLog> list = new ArrayList<>();
                for (int i = 0; i < 15; i++) {
                    time = DateUtil.addMinutes(time, -random.nextInt(5));
                    Gps gps1 = new Gps(appEmpData.getLat(), appEmpData.getLng());
                    Gps randomLatLng = PositionUtil.getRandomLatLng(gps1);
                    AppDeviceCardLog log = new AppDeviceCardLog();
                    log.setEmpId(empId);
                    log.setDeviceId(appEmpData.getDeviceId());
                    log.setTime(time);
                    log.setLat(randomLatLng.getLat());
                    log.setLng(randomLatLng.getLng());
                    log.setLatWgs84(randomLatLng.getLat());
                    log.setLngWgs84(randomLatLng.getLng());
                    log.setBatteryPower(appEmpData.getBatteryPower());

                    MapLoc loc = mapApi.geocode(randomLatLng.getLng(), randomLatLng.getLat());
                    log.setLocation(loc.getAddress());
                    log.setDelFlag(DelFlag.UNDELETE.getValue());
                    list.add(log);
                }
                appDeviceCardLogDao.batchInsert(list);
                cnt++;
            } catch (Exception e) {
                continue;
            }
        }
        logger.info("成功添加安全帽数据{}个", cnt);
    }

    @Override
    public void cleanEmpAttendRecord(Date startTime, Date endTime) throws BizException {
        logger.info("清理人员考勤记录脏数据,startTime:{},endTime:{}", startTime, endTime);
        dirtyDataCleaner.cleanEmpAttendRecord(startTime, endTime);
    }

    @Override
    public void cleanFacegateRecord(Date startTime, Date endTime) throws BizException {
        logger.info("清理闸机识别记录脏数据,startTime:{},endTime:{}", startTime, endTime);
        dirtyDataCleaner.clearFacegateRecord(startTime, endTime);
    }

    @Override
    public void sendMqttMessage(MqttMessageParam param) {
        if (mqttEnable == null || !mqttEnable) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "MQTT暂未启用");
        }
        String topic = param.getTopic();
        Integer qos = param.getQos();
        String payload = param.getPayload();
        if (qos != null) {
            mqttMessageSender.sendToMqtt(topic, qos, payload);
        } else {
            mqttMessageSender.sendToMqtt(topic, payload);
        }
    }

    @Override
    public void updateEmpWorkType() throws BizException {
        List<AppEmp> list = appEmpMapper.selectOddWorkTypeEmp();
        for (AppEmp appEmp : list) {
            String workTypeName = appEmp.getWorkTypeName();
            Integer deptId = appEmp.getDeptId();
            AppEmpWorkType empWorkType = appEmpWorkTypeMapper.selectByDeptIdAndName(deptId, workTypeName);
            if (empWorkType == null) {
                empWorkType = new AppEmpWorkType();
                empWorkType.setDeptId(deptId);
                empWorkType.setName(workTypeName);
                appEmpWorkTypeMapper.insertSelective(empWorkType);
            }
            // 更新人员工种
            appEmp.setWorkTypeId(empWorkType.getId());
            appEmp.setWorkTypeName(empWorkType.getName());
            appEmpMapper.updateByPrimaryKeySelective(appEmp);
        }
    }
}
